import { CSLineSegments, CSMesh } from '@amcax/base';
import {
  previewEdgeMaterial,
  previewMeshEdgeMaterial,
  previewMeshMaterial,
} from '@amcax/renderer';
import { BufferAttribute, BufferGeometry, Object3D } from 'three-legacy';

export const getTempMesh = (model: any) => {
  const curModel: Object3D & { model?: any } = new Object3D();
  curModel.name = model.id;
  const edges = model.edges || [];
  const edgesVertices = [];
  for (let i = 0, l = edges.length; i < l; i++) {
    const edge = edges[i];
    if (edge.meshType == 'index') {
      // meshType 为 index 的情况，暂时不支持临时面
    } else {
      // 默认 meshType 是 point
      const edgeLength = edge.mesh.length;
      for (let j = 0; j < edgeLength; j++) {
        edgesVertices.push(...edge.mesh[j]);
        // 不是起始点和结束点，需要重复一次，这样才能渲染出连续的线（而不是虚线）
        if (j != 0 && j != edgeLength - 1) {
          edgesVertices.push(...edge.mesh[j]);
        }
      }
    }
  }

  const edgeBuffer = new Float32Array(edgesVertices);
  const edgeGeometry = new BufferGeometry();
  edgeGeometry.attributes.position = new BufferAttribute(edgeBuffer, 3);
  const faces = model.faces;
  if (faces) {
    const facesVertices = model.points.flat();
    const facetsIndexArr = [];
    for (let i = 0, l = faces.length; i < l; i++) {
      const face = faces[i];
      face.facets.forEach((segment) => {
        facetsIndexArr.push(...segment);
      });
    }
    const faceBuffer = new Float32Array(facesVertices);
    const indexBuffer = new Uint32Array(facetsIndexArr);
    const faceGeometry = new BufferGeometry();
    faceGeometry.attributes.position = new BufferAttribute(faceBuffer, 3);
    const indexAttribute = new BufferAttribute(indexBuffer, 1);
    faceGeometry.setIndex(indexAttribute);
    const mesh = new CSMesh({
      geometry: faceGeometry,
      material: previewMeshMaterial,
      modelDxid: model?.id,
      shapeId: model?.id,
    });
    curModel.add(mesh);
  }

  const previewLine = new CSLineSegments({
    geometry: edgeGeometry.clone(),
    material: faces ? previewMeshEdgeMaterial : previewEdgeMaterial,
  });
  curModel.add(previewLine);
  return curModel;
};
